/*
/*
 Problem Description
　　给定一个m × n (m行, n列)的迷宫，迷宫中有两个位置，gloria想从迷宫的一个位置走到另外一个位置，
当然迷宫中有些地方是空地，gloria可以穿越，有些地方是障碍，她必须绕行，从迷宫的一个位置，
只能走到与它相邻的4个位置中,当然在行走过程中，gloria不能走到迷宫外面去。
令人头痛的是，gloria是个没什么方向感的人，因此，她在行走过程中，不能转太多弯了，否则她会晕倒的。
我们假定给定的两个位置都是空地，初始时，gloria所面向的方向未定，她可以选择4个方向的任何一个出发，
而不算成一次转弯。gloria能从一个位置走到另外一个位置吗？
 
Input
　　第1行为一个整数t (1 ≤ t ≤ 100),表示测试数据的个数，接下来为t组测试数据，每组测试数据中，
　　第1行为两个整数m, n (1 ≤ m, n ≤ 100),分别表示迷宫的行数和列数，接下来m行，每行包括n个字符，
其中字符'.'表示该位置为空地，字符'*'表示该位置为障碍，输入数据中只有这两种字符，
每组测试数据的最后一行为5个整数k, x1, y1, x2, y2 (1 ≤ k ≤ 10, 1 ≤ x1, x2 ≤ n, 1 ≤ y1, y2 ≤ m),
其中k表示gloria最多能转的弯数，(x1, y1), (x2, y2)表示两个位置，其中x1，x2对应列，y1, y2对应行。
 
Output
　　每组测试数据对应为一行，若gloria能从一个位置走到另外一个位置，输出“yes”，否则输出“no”。
 
Sample Input
2
5 5
...**
*.**.
.....
.....
 *....
1 1 1 1 3
5 5
...**
*.**.
.....
.....
 *....
2 1 1 1 3
 
Sample Output
no
yes
 */

package com.yuan.algorithms.training201607;

import java.util.Scanner;

/**
 * @author YouYuan
 * @contact 1265161633@qq.com
 * @date 2016年8月6日 上午10:44:03
 * @descript 
 */
public class HDU1728逃离迷宫_搜索剪枝 {

	static int m, n, k, endX, endY;
	/**地图*/
	static char[][] map = new char[105][105];;
	/**记录拐弯次数*/
	static int[][] swerve = new int[105][105];  
	/**方向：上下左右*/
    static int dir[][] = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } };  
	static boolean result;// 记录结果

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while (sc.hasNext()) {
			int t = sc.nextInt();
			for (int i = 0; i < t; i++) {
				result = false;
				m = sc.nextInt();
				n = sc.nextInt();
				for (int j = 0; j < m; j++) {
					String x = sc.next();
					for (int k = 0; k < n; k++) {
						map[j][k] = x.charAt(k);
						swerve[j][k] = Integer.MAX_VALUE;//拐弯次数初始化为最大值
					}
				}
				k = sc.nextInt();// 能转弯的次数
				int startY = sc.nextInt() - 1;// 起点Y坐标
				int startX = sc.nextInt() - 1;// 起点X坐标
				endY = sc.nextInt() - 1;// 终点Y坐标
				endX = sc.nextInt() - 1;// 终点X坐标
				swerve[startX][startY] = 0;//设置起点的拐弯次数为0
				search(startX, startY, -1);
				if (result) {
					System.out.println("yes");
				} else {
					System.out.println("no");
				}
			}
		}
	}

	/**
	 * 
	 * @param x X坐标
	 * @param y Y坐标
	 * @param direction 方向代码（0：上， 1：下， 2：左， 3：右），第一次访问为-1，不算拐弯次数
	 */
	private static void search(int x, int y, int direction) {
		if (result) {// 找到结果，终止搜索
			return;
		}
		//判断搜索位置是否越界
		if (x < 0 || x >= m || y < 0 || y >= n) {
			return;
		}
		//拐弯次数是否用完
		if (swerve[x][y] > k) {
			return;
		}
		//是否到达终点
		if (x == endX && y == endY) {
			result = true;
			return;
		}
		for (int i = 0; i < dir.length; i++) {
			int newX = x + dir[i][0];//获得新的位置坐标
			int newY = y + dir[i][1];
			//如果地图不可走，则跳过
			if (newX < 0 || newX >= m || newY < 0 || newY >= n) {
				continue;
			}
			if (map[newX][newY] != '.') {
				continue;
			}
			/**
			 * 未访问的点的拐弯次数默认设置为最大值，
			 * 如果原位置的拐弯次数大于或等于新位置，
			 * 说明新位置曾经被访问过了，并且此次搜索不比原来的搜索优
			 * 此时是重复访问，跳过
			 */
			if (swerve[x][y] >= swerve[newX][newY]) {
				continue;
			}
			swerve[newX][newY] = swerve[x][y];//更新新位置的拐弯次数为上一个位置的拐弯次数
			//不是第一次搜索并且方向与原来的方向不同，则拐弯次数+1
			if (direction != -1 && direction != i) {
				swerve[newX][newY]++;
			}
			search(newX, newY, i);//使用新的位置和方向递归到下层继续搜索
		}
	}
}
